home *** CD-ROM | disk | FTP | other *** search
- (*===========================================================================*)
- (* Overlay processor *)
- (* *)
- (* Copyright 1988, 1989, 1990, 1991 by H. Roy Engehausen. All rights *)
- (* reserved. *)
- (* *)
- (*===========================================================================*)
-
- {$UNDEF DEBUG}
- {$UNDEF DEBUG_INIT} (* Debug initialize *)
-
- UNIT BBOVER;
-
- INTERFACE
-
- TYPE
- byte_ptr = ^BYTE;
-
- FUNCTION use_overlay(entry_point : byte_ptr;
- time_to_wait_for_overlay : BYTE
- ) : BOOLEAN;
-
- PROCEDURE free_overlay;
-
- PROCEDURE overlay_save;
- PROCEDURE overlay_restore;
-
- IMPLEMENTATION
-
- USES
- CRT,
- OVERLAY,
- bbbug,
- bbdummy,
- bbdump,
- bbsema2,
- bbstr,
- bbtask,
- bbtime,
- bbwin;
-
- (*===========================================================================*)
- (* Globals *)
- (*===========================================================================*)
-
- (*===========================================================================*)
- (* Use a certain overlay *)
- (* Return true when we can use overlay *)
- (*===========================================================================*)
-
- FUNCTION use_overlay(entry_point : byte_ptr;
- time_to_wait_for_overlay : BYTE
- ) : BOOLEAN;
-
- VAR
- b : BOOLEAN;
- i : BYTE;
- s_type : semaphore_type; (* True when things are OK *)
- time_out : LONGINT;
-
- BEGIN;
-
- use_overlay := TRUE;
- EXIT;
-
- END;
-
- (*===========================================================================*)
- (* Free an overlay *)
- (*===========================================================================*)
-
- PROCEDURE free_overlay;
-
- BEGIN;
-
- END;
-
- (*===========================================================================*)
- (* Overlay_save *)
- (* Save info about overlay usage in the stack *)
- (*===========================================================================*)
-
- PROCEDURE overlay_save;
-
- VAR
- stack_frame_ptr : stack_frame_ptr_type;
- over_head : over_head_type;
- found : BOOLEAN;
- work : WORD;
-
- LABEL
- inc_count_and_next_stack_item,
- next_stack_item;
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Initialize things *)
- (*-----------------------------------------------------------------------*)
-
- over_head.off := 0;
-
- (*-----------------------------------------------------------------------*)
- (* Set the overlay fixup count to zero for now *)
- (*-----------------------------------------------------------------------*)
-
- active_tcb^.tcb_ovr_cnt := 0;
-
- (*-----------------------------------------------------------------------*)
- (* Get the current setting of BP *)
- (*-----------------------------------------------------------------------*)
-
- ASM;
- MOV work,BP
- END;
- stack_frame_ptr.pnt := PTR(SSEG, work);
-
- (*-----------------------------------------------------------------------*)
- (* Loop back thru the stack *)
- (*-----------------------------------------------------------------------*)
-
- REPEAT
-
- {$IFDEF DEBUG_1}
- WRITELN('Save stack frame at ', bp);
-
- WRITELN( stack_frame_ptr^.link_seg,
- ':', stack_frame_ptr^.link_off,
- ' -- ', stack_frame_ptr^.next_bp);
- DELAY(1000);
- {$ENDIF}
-
- (*---------------------------------------------------------------------*)
- (* See if in overlay buffer *)
- (*---------------------------------------------------------------------*)
-
- IF stack_frame_ptr.pnt^.link_seg >= OvrHeapOrg THEN
- BEGIN;
-
- {$IFDEF DEBUG_1}
- WRITELN('In buffer ', stack_frame_ptr.pnt^.link_seg, '/', OvrHeapOrg);
- {$ENDIF}
-
- (*-----------------------------------------------------------------*)
- (* Search overlay list looking for the right header *)
- (*-----------------------------------------------------------------*)
-
- over_head.seg := OvrLoadList;
-
- found := FALSE;
- work := stack_frame_ptr.pnt^.link_seg;
- REPEAT
- IF over_head.pnt^.load_segment = work THEN
- found := TRUE
- ELSE
- over_head.seg := over_head.pnt^.load_list_next;
- UNTIL found OR (over_head.seg = 0);
-
- (*-----------------------------------------------------------------*)
- (* If we didn't find it then die *)
- (*-----------------------------------------------------------------*)
-
- IF NOT found THEN
- BEGIN;
- WRITELN('Overlay ptr bad --', w2x(stack_frame_ptr.pnt^.link_seg),
- '/', w2x(OvrHeapOrg),
- '@', p2x(stack_frame_ptr.pnt));
- dump_hex(stack_frame_ptr.pnt^.link_ptr, 20);
- dump_all;
- HALT;
- END;
-
- stack_frame_ptr.pnt^.link_seg := over_head.seg;
-
- (*-----------------------------------------------------------------*)
- (* Go to next item in stack *)
- (*-----------------------------------------------------------------*)
-
- GOTO inc_count_and_next_stack_item;
-
- END;
-
- (*---------------------------------------------------------------------*)
- (* See if the segment can be used as a pointer to an overlay header. *)
- (* If not go to next one *)
- (*---------------------------------------------------------------------*)
-
- over_head.seg := stack_frame_ptr.pnt^.link_seg;
-
- IF over_head.pnt^.return_int <> int3f THEN
- GOTO next_stack_item;
-
- (*---------------------------------------------------------------------*)
- (* If the link offset is zero then the link points to the INT $3F in *)
- (* the overlay header and we need to get the offset from the header. *)
- (* If not, then the offset is already in the stack *)
- (*---------------------------------------------------------------------*)
-
- IF stack_frame_ptr.pnt^.link_off = 0 THEN
- stack_frame_ptr.pnt^.link_off := over_head.pnt^.return_ofs;
-
- (*---------------------------------------------------------------------*)
- (* Bump count of saved overlay info *)
- (*---------------------------------------------------------------------*)
-
- inc_count_and_next_stack_item:
-
- INC(active_tcb^.tcb_ovr_cnt);
-
- (*---------------------------------------------------------------------*)
- (* Chain down the stack *)
- (*---------------------------------------------------------------------*)
-
- next_stack_item:
-
- stack_frame_ptr.off := stack_frame_ptr.pnt^.next_bp;
-
- UNTIL stack_frame_ptr.pnt^.next_bp = 0; (*----- End loop thru stack -----*)
-
- END;
-
- (*===========================================================================*)
- (* Overlay_restore *)
- (* Restore info about overlay usage into the stack *)
- (*===========================================================================*)
-
- PROCEDURE overlay_restore;
-
- VAR
- stack_frame_ptr : stack_frame_ptr_type;
- over_head : over_head_type;
- found : BOOLEAN;
- down_count : BYTE;
- loop_count : BYTE;
- used_count : BYTE;
- overlay_used : ARRAY[1..20] OF WORD;
- work : WORD;
-
- LABEL
- found_it,
- next_stack_item;
-
- BEGIN;
-
- over_head.off := 0;
- used_count := 0;
-
- down_count := active_tcb^.tcb_ovr_cnt;
-
- (*-----------------------------------------------------------------------*)
- (* Get the current setting of BP *)
- (*-----------------------------------------------------------------------*)
-
- ASM;
- MOV work,BP
- END;
- stack_frame_ptr.pnt := PTR(SSEG, work);
-
- (*-----------------------------------------------------------------------*)
- (* Loop back thru the stack *)
- (*-----------------------------------------------------------------------*)
-
- WHILE down_count > 0 DO
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* See if the segment can be used as a pointer to an overlay header. *)
- (* If not go to next one *)
- (*-------------------------------------------------------------------*)
-
- over_head.seg := stack_frame_ptr.pnt^.link_seg;
-
- IF over_head.pnt^.return_int <> int3f THEN
- GOTO next_stack_item;
-
- DEC(down_count);
-
- (*-------------------------------------------------------------------*)
- (* See if the module is in storage and not on probation. *)
- (*-------------------------------------------------------------------*)
-
- IF (over_head.pnt^.load_segment <> 0)
- AND (over_head.pnt^.first_entry <> int3f) THEN
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* Module is in storage. Put out the correct link info *)
- (*---------------------------------------------------------------*)
-
- stack_frame_ptr.pnt^.link_seg := over_head.pnt^.load_segment;
-
- (*---------------------------------------------------------------*)
- (* Done with this stack frame *)
- (*---------------------------------------------------------------*)
-
- GOTO next_stack_item;
-
- END; (*----- End of fixup of in-storage overlay -------------------*)
-
- (*-------------------------------------------------------------------*)
- (* Module is not currently loaded *)
- (*-------------------------------------------------------------------*)
-
- (*-------------------------------------------------------------------*)
- (* Determine if we have already fixed up a reference to this module *)
- (*-------------------------------------------------------------------*)
-
- found := FALSE;
- FOR loop_count := 1 TO used_count DO
- IF over_head.seg = overlay_used[loop_count] THEN
- BEGIN;
- found := TRUE;
- GOTO found_it;
- END;
-
- found_it:
-
- (*-------------------------------------------------------------------*)
- (* If no previous reference then put the offset into the header and *)
- (* point the link to the INT $3F. Save the fact that we did do this *)
- (* module *)
- (*-------------------------------------------------------------------*)
-
- IF NOT found THEN
- BEGIN;
- over_head.pnt^.return_ofs := stack_frame_ptr.pnt^.link_off;
- stack_frame_ptr.pnt^.link_off := 0;
-
- INC(used_count);
- overlay_used[used_count] := over_head.seg;
- END;
-
- (*-------------------------------------------------------------------*)
- (* Chain down the stack *)
- (*-------------------------------------------------------------------*)
-
- next_stack_item:
-
- stack_frame_ptr.off := stack_frame_ptr.pnt^.next_bp;
-
- IF stack_frame_ptr.off = 0 THEN
- BEGIN;
- WRITELN('Popped whole overlay stack');
- HALT;
- END;
-
- END; (*----- End loop thru stack -------------------------------------*)
-
- END;
-
- END.